/**
 * 路由系统
 * 支持跨项目路由分发
 */
const AppError = require('./app_error.js');
const AppUtil = require('./app_util.js');
const RouteHelper = require('./route_helper.js');
const AppAuth = require('./app_auth.js');

// 最大路由嵌套深度，防止循环调用
const MAX_ROUTE_DEPTH = 5;

/**
 * 路由器主类
 */
class AppRouter {
  /**
   * 路由处理函数
   * @param {Object} param0 路由配置和请求信息
   * @returns {Promise<Object>} 处理结果
   */
  static async router({ routes, event, context, depth = 0 }) {
    if (!routes || !event) {
      console.error('[Router] 缺少必要的路由参数');
      return AppUtil.handlerSvrErr('缺少必要参数');
    }
    
    // 防止路由深度过大
    if (depth >= MAX_ROUTE_DEPTH) {
      console.error('[Router] 路由嵌套深度超过限制');
      return AppUtil.handlerSvrErr('路由嵌套深度超过限制');
    }
    
    const route = event.route;
    if (!route) {
      console.error('[Router] 缺少路由信息');
      return AppUtil.handlerSvrErr('缺少路由信息');
    }
    
    console.log(`[Router] 处理路由: ${route}`);
    
    try {
      // 解析路由信息
      const routeInfo = RouteHelper.parseRoute(route);
      
      // 对于跨项目API，进行认证和项目切换
      if (routeInfo.isCrossProjectApi) {
        console.log(`[Router] 检测到跨项目API: ${route}`);
        
        // 认证跨项目调用权限
        if (!event._authResult) {
          const authResult = await AppAuth.authMiddleware(event);
          event._authResult = authResult;
        }
        
        // 设置全局PID
        if (global.PID !== routeInfo.pid) {
          console.log(`[Router] 切换项目: ${global.PID} -> ${routeInfo.pid}`);
          global.PID = routeInfo.pid;
        }
        
        // 使用解析后的实际路由路径
        const targetRoute = routeInfo.routePath;
        if (targetRoute !== route) {
          console.log(`[Router] 跨项目路由转换: ${route} -> ${targetRoute}`);
          
          // 加载目标项目路由配置
          const targetRoutes = require(`../../project/${routeInfo.pid}/public/route.js`);
          
          // 为目标路径创建新的事件对象
          const newEvent = { ...event, route: targetRoute };
          
          // 递归处理
          return await this.router({ 
            routes: targetRoutes, 
            event: newEvent, 
            context, 
            depth: depth + 1 
          });
        }
      }
      
      // 系统路由处理
      if (routeInfo.isSystemRoute) {
        console.log(`[Router] 检测到系统路由: ${route}`);
        
        // 加载系统路由配置
        const systemRoutes = require('../../project/comm/public/route.js');
        
        // 递归处理
        return await this.router({ 
          routes: systemRoutes, 
          event, 
          context, 
          depth: depth + 1 
        });
      }
      
      // 获取控制器和方法
      const { controller, action } = RouteHelper.getController(route, routes);
      
      // 加载控制器
      const ControllerClass = this._loadController(controller, routeInfo.pid);
      if (!ControllerClass) {
        console.error(`[Router] 未找到控制器: ${controller}`);
        return AppUtil.handlerSvrErr('无效的控制器');
      }
      
      // 创建控制器实例
      const controllerObj = new ControllerClass();
      
      // 检查方法是否存在
      if (typeof controllerObj[action] !== 'function') {
        console.error(`[Router] 未找到方法: ${controller}@${action}`);
        return AppUtil.handlerSvrErr('无效的方法');
      }
      
      // 初始化控制器
      if (controllerObj.initParams) {
        await controllerObj.initParams(event, context);
      }
      
      // 跨项目上下文
      if (routeInfo.isCrossProjectApi) {
        controllerObj._crossContext = RouteHelper.createCrossContext(route, event);
      }
      
      // 执行方法
      console.log(`[Router] 调用方法: ${controller}@${action}`);
      const result = await controllerObj[action]();
      
      return result;
    } catch (err) {
      console.error('[Router] 路由处理异常:', err);
      
      // 自定义错误直接返回
      if (err instanceof AppError) {
        return AppUtil.handlerSvrErr(err.message, err.code);
      }
      
      // 其他错误返回通用服务错误
      return AppUtil.handlerSvrErr('服务器内部错误');
    }
  }
  
  /**
   * 加载控制器
   * @param {String} controller 控制器名称
   * @param {String} pid 项目标识
   * @returns {Class} 控制器类
   */
  static _loadController(controller, pid) {
    try {
      // 尝试从项目目录加载
      const controllerPath = `../../project/${pid}/controller/${controller}.js`;
      return require(controllerPath);
    } catch (err) {
      console.error(`[Router] 加载控制器失败: ${controller}, 错误:`, err);
      return null;
    }
  }
}

module.exports = AppRouter; 